package com.chenfan.mcn.job;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.chenfan.common.utils.DateUtils;
import com.chenfan.mcn.constant.McnConstant;
import com.chenfan.mcn.dao.BusinessCommissionReturnMapper;
import com.chenfan.mcn.dao.QuarterMapper;
import com.chenfan.mcn.model.BusinessCommissionReturn;
import com.chenfan.mcn.model.Quarter;
import com.chenfan.mcn.extension.rule.ComputableRuleEngine;
import com.chenfan.mcn.rule.ReturnFactorComputableRule;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.List;

/**
 * 收入合同-回款率&回款系数JOB
 *
 * @author wulg
 * @date 2021-09-15
 **/
@Slf4j
@RefreshScope
public class ReturnRateAndFactorJob {

    @Value("${bc.return.earliest-start-date : 2021-09-01 00:00:00}")
    private String earliestStartDateStr;

    @Autowired
    private QuarterMapper quarterMapper;

    @Autowired
    private BusinessCommissionReturnMapper bcReturnMapper;

    @XxlJob(value = "returnRateAndFactor")
    public ReturnT<String> returnRateAndFactor(String param) {
        Date taskDate = new Date();
        Date earliestStartDate = null;
        try {
            earliestStartDate = DateUtils.parseDate(earliestStartDateStr, McnConstant.LONG_DATE_FORMAT);
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
            return ReturnT.FAIL;
        }
        Quarter quarter = quarterMapper.getPreQuarter();
        //测试MOCK-季度
        if (StringUtils.isNotBlank(param) && Boolean.valueOf(param).booleanValue()) {
            Date now = new Date();
            quarter = quarterMapper.selectOne(Wrappers.lambdaQuery(Quarter.class).le(Quarter::getStartTime, now).ge(Quarter::getEndTime, now));
        }
        if (quarter == null) {
            log.error("获取不到上个季度对象！任务执行日期：{}", DateUtils.formatDate(taskDate, McnConstant.LONG_DATE_FORMAT));
            //初始化，目前quarter表已经统一初始化
            return ReturnT.FAIL;
        }
        if (earliestStartDate != null && earliestStartDate.after(quarter.getStartTime()) && earliestStartDate.before(quarter.getEndTime())) {
            quarter.setStartTime(earliestStartDate);
        }
        //判断是否存在
        boolean exist = bcReturnMapper.exist(Wrappers.lambdaQuery(BusinessCommissionReturn.class).eq(BusinessCommissionReturn::getQuarterCode, quarter.getQuarterCode()));
        if (exist) {
            log.error("重复执行！季度编号：{}，任务执行日期：{}", quarter.getQuarterCode(), DateUtils.formatDate(taskDate, McnConstant.LONG_DATE_FORMAT));
            return ReturnT.FAIL;
        }
        List<BusinessCommissionReturn> dataList = bcReturnMapper.summaryReturn(quarter.getStartTime(), quarter.getEndTime());
        if (CollectionUtils.isEmpty(dataList)) {
            log.info("统计无数据！季度编号：{}，任务执行日期：{}", quarter.getQuarterCode(), DateUtils.formatDate(taskDate, McnConstant.LONG_DATE_FORMAT));
            return ReturnT.SUCCESS;
        }
        Date now = new Date();
        Quarter finalQuarter = quarter;
        dataList.forEach(data -> {
            data.setQuarterCode(finalQuarter.getQuarterCode());
            if (BigDecimal.ZERO.compareTo(data.getTotalBusinessAmount()) == 0) {
                data.setReturnRate(BigDecimal.ONE);
                data.setReturnFactor(BigDecimal.ONE);
            } else if (BigDecimal.ZERO.compareTo(data.getTotalPaybackAmount()) == 0) {
                data.setReturnRate(BigDecimal.ZERO);
                data.setReturnFactor(BigDecimal.ZERO);
            } else {
                /**
                 * 部门回款率统计逻辑：
                 *    2021年第三季度回款率时间统计规则从2021年9月1日0点开始到第三季度末；后面季度时间按照正常季度时间统计，例如1月1号0点到3月31号晚上23:59:59秒。
                 *    每个季度结束的当天23:59:59秒的时候需要落库记录每个商务部门（客户部）当前季度的回款率，不再更新
                 *  1、本季度签单金额：本部门下（收入合同所属部门为本部门）【收入合同创建时间为本季度时间内】（审批通过状态）的【商务确认合同金额】累计。
                 *  2、本季度实际回款金额：本部门下（收入合同所属部门为本部门）【收入合同创建时间为本季度时间内】（审批通过状态）的【回款金额】累计。
                 *  3、回款率=本季度实际回款金额/本季度签单金额（百分号前面数字四舍五入保留两位小数）
                 */
                data.setReturnRate(data.getTotalPaybackAmount().divide(data.getTotalBusinessAmount(), 4, BigDecimal.ROUND_HALF_UP));
                /**
                 *回款率达成70%及以上，则回款系数为100%
                 * 回款率（含）65%-70%（不含），回款系数为90%
                 * 回款率（含）60%-65%（不含），回款系数为80%
                 * 回款率（含）55%-60%（不含），回款系数为70%
                 * 回款率（含）50%-55%（不含），回款系数为60%
                 * 按5%的档位回款系数减10%以此类推，回款系数最低为0%
                 */
                data.setReturnFactor(ComputableRuleEngine.fire(ReturnFactorComputableRule.class, data.getReturnRate()));
            }
            data.setStartTime(finalQuarter.getStartTime());
            data.setEndTime(finalQuarter.getEndTime());
            data.setTaskDate(taskDate);
            data.setCreateDate(now);
            data.setIsDelete(Boolean.FALSE);
        });
        //统计维度-数据量不大，暂不用分批插入
        bcReturnMapper.insertBatch(dataList);
        return ReturnT.SUCCESS;
    }
}
